package net.suncaper.mvc.utils;

import com.alibaba.druid.pool.DruidDataSourceFactory;

import javax.sql.DataSource;
import java.io.IOException;
import java.io.InputStream;
import java.sql.Connection;
import java.sql.SQLException;
import java.util.Properties;

/**
 * JDBC工具类
 */
public class JDBCUtils {
    /**
     * 数据源
     */
    private static DataSource dataSource;

    /**
     * 同一个线程共享的数据库连接
     */
    private static ThreadLocal<Connection> threadLocal = new ThreadLocal<>();

    /**
     * 初始化数据源及数据库连接池
     */
    static {
        try {
            // 创建一个Properties的对象
            Properties properties = new Properties();
            // 加载配置文件
            InputStream inputStream = JDBCUtils.class.getClassLoader().getResourceAsStream("db.properties");
            properties.load(inputStream);

            // 创建DataSource
            dataSource = DruidDataSourceFactory.createDataSource(properties);
        } catch (IOException e) {
            throw new RuntimeException(e);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * 获取数据库连接
     */
    public static Connection getConnection() {
        // 先从ThreadLocal获取数据库连接
        Connection connection = threadLocal.get();

        // 如果从ThreadLocal没有获取到connection，就从连接池获取
        if (connection == null) {
            try {
                connection = dataSource.getConnection();
                // 将连接存入ThreadLocal
                threadLocal.set(connection);
            } catch (SQLException e) {
                throw new RuntimeException(e);
            }
        }

        return connection;
    }

    /**
     * 开启事务
     */
    public static void beginTransaction() {
        try {
            Connection connection = getConnection();
            connection.setAutoCommit(false);
        } catch (SQLException e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * 提交事务
     */
    public static void commitTransaction() {
        Connection connection = null;
        try {
            connection = getConnection();
            connection.commit();
        } catch (SQLException e) {
            throw new RuntimeException(e);
        } finally {
            close();
        }
    }

    /**
     * 回滚事务
     */
    public static void rollbackTransaction() {
        Connection connection = null;
        try {
            connection = getConnection();
            connection.rollback();
        } catch (SQLException e) {
            throw new RuntimeException(e);
        } finally {
            close();
        }
    }

    /**
     * 释放数据库连接
     */
    public static void close() {
        // 先从ThreadLocal获取数据库连接
        Connection connection = threadLocal.get();

        // 获取的connection不为null才进行释放
        if (connection != null) {
            // 从ThreadLocal移除
            threadLocal.remove();
            try {
                // 释放连接（这里是回收到Druid连接池）
                connection.close();
            } catch (SQLException e) {
                throw new RuntimeException(e);
            }
        }
    }
}